package org.zakariya.stickyheadersapp.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.VectorElement;
import ohos.agp.utils.Color;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.Revocable;
import org.zakariya.stickyheaders.ActionType;
import org.zakariya.stickyheaders.StickyHeaderLayoutManager;
import org.zakariya.stickyheaders.Utils;
import org.zakariya.stickyheaders.callback.ClickCallback;
import org.zakariya.stickyheaders.model.HeaderModel;
import org.zakariya.stickyheaders.model.ItemModel;
import org.zakariya.stickyheaders.model.Model;
import org.zakariya.stickyheadersapp.ResourceTable;
import org.zakariya.stickyheadersapp.adapter.MultipleSelectionAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
 * MultipleSelectionAbilitySlice
 *
 * @since 2021-08-20
 */
public class MultipleSelectionAbilitySlice extends AbilitySlice {
    private MultipleSelectionAdapter adapter;
    private List<ItemModel> dataList;
    private List<ItemModel> temp = new ArrayList<>();
    private List<ItemModel> copyData = new ArrayList<>();
    private boolean isCopy;
    private ShapeElement selectElement;
    private ShapeElement normalElement;
    private Text copy;
    private Text delete;
    private ListContainer listContainer;
    private ItemModel model = null;
    private DependentLayout toolbar;
    private DependentLayout toolbar_delete;
    private boolean isRepeat = false;
    private int check_number = 0;
    private Text tv_selection;
    private CopyRun copyRun;
    private int copyPosition;
    private Revocable copyRevocable;
    private TaskDispatcher copyTaskDispatcher;
    private AnimatorValue animationOut;
    private Text tv_ok;
    private DirectionalLayout dl_bottom;
    private final HashMap<String, ArrayList<ItemModel>> map = new HashMap<>();
    private StickyHeaderLayoutManager headerDecor;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_multiple_selection);
        initComponent();
        initClick();
        initBackground();
    }

    private void initComponent() {
        Image image = (Image) findComponentById(ResourceTable.Id_icon_back);
        image.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                terminateAbility();
            }
        });
        Image image_buck = (Image) findComponentById(ResourceTable.Id_icon_back_delete);
        image_buck.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                toolbar.setVisibility(Component.VISIBLE);
                toolbar_delete.setVisibility(Component.HIDE);
                copyData.clear();
                isCopy = false;
                check_number = 0;
                if (copyRevocable != null) {
                    copyRevocable.revoke();
                    copyPosition = 0;
                }
                adapter.notifyDataChanged();
            }
        });
        toolbar = (DependentLayout) findComponentById(ResourceTable.Id_toolbar);
        toolbar_delete = (DependentLayout) findComponentById(ResourceTable.Id_toolbar_delete);
        Text headerText = (Text) findComponentById(ResourceTable.Id_multiple_text);
        tv_ok = (Text) findComponentById(ResourceTable.Id_tv_ok);
        dl_bottom = (DirectionalLayout) findComponentById(ResourceTable.Id_dl_bottom);
        tv_selection = (Text) findComponentById(ResourceTable.Id_tv_selection);
        copy = (Text) findComponentById(ResourceTable.Id_tv_copy);
        delete = (Text) findComponentById(ResourceTable.Id_tv_delete);
        listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_multiple_callbacks);
        DependentLayout layout = (DependentLayout) findComponentById(ResourceTable.Id_layout_overlap);
        Button collapse = (Button) findComponentById(ResourceTable.Id_collapseBtn);
        dataList = Utils.getMultipleSelectionList(999, 5, true);
        adapter = new MultipleSelectionAdapter(this, dataList, mClickCallback);
        listContainer.setItemProvider(adapter);
        headerDecor = new StickyHeaderLayoutManager(listContainer, layout, headerText, null, collapse, mClickCallback);
        headerDecor.setDataList(dataList,true);
        tv_selection.setText(check_number + " selection");
    }

    private void initBackground() {
        selectElement = new ShapeElement();
        selectElement.setRgbColor(new RgbColor(169, 169, 169));
        normalElement = new ShapeElement();
        normalElement.setRgbColor(new RgbColor(Color.WHITE.getValue()));
    }

    private void initClick() {
        listContainer.addScrolledListener((component, i, i1, i2, i3) -> {
            copyPosition = 0;
            if (isCopy) {
                int count = listContainer.getVisibleIndexCount() + listContainer.getFirstVisibleItemPosition();
                for (ItemModel copyDatum : copyData) {
                    for (int position = 0; position < dataList.size(); position++) {
                        ItemModel itemModel1 = dataList.get(position);
                        if (copyDatum.getTitle().equals(itemModel1.getTitle())) {
                            if (position < count && position >= listContainer.getFirstVisibleItemPosition()) {
                                listContainer.getComponentAt(position).setBackground(selectElement);
                            }
                        }
                    }
                }
            }
        });
        tv_ok.setClickedListener(component -> dissMiss());
        tv_ok.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                dissMiss();
            }
        });
        copy.setClickedListener(component -> {
            addCopy();
            adapter.notifyDataChanged();
            copyData.clear();
            toolbar.setVisibility(Component.VISIBLE);
            toolbar_delete.setVisibility(Component.HIDE);
            isCopy = false;
            check_number = 0;
            if (copyRevocable != null) {
                copyRevocable.revoke();
                copyPosition = 0;
            }
        });
        delete.setClickedListener(component -> {
            dataList.removeAll(copyData);
            adapter.notifyDataChanged();
            copyData.clear();
            toolbar.setVisibility(Component.VISIBLE);
            toolbar_delete.setVisibility(Component.HIDE);
            isCopy = false;
            check_number = 0;
            if (copyRevocable != null) {
                copyRevocable.revoke();
                copyPosition = 0;
            }
        });
        listContainer.setItemLongClickedListener((listContainer, component, i, l) -> {
            toolbar.setVisibility(Component.HIDE);
            toolbar_delete.setVisibility(Component.VISIBLE);
            Model model = dataList.get(i);
            if (!model.isHeader()) {
                copyRun = new CopyRun(i);
                copyRun.run();
                if (!isCopy) {
                    check_number++;
                    copyData.add(0, dataList.get(i));
                    tv_selection.setText(check_number + " selection");
                    component.setBackground(selectElement);
                }
            }
            isCopy = true;
            tv_selection.setText(check_number + " selection");
            return true;
        });

        listContainer.setItemClickedListener((listContainer, component, i, l) -> {
            Model model = dataList.get(i);
            if (!model.isHeader()) {
                if (isCopy) {
                    if (copyPosition != 0) {
                        listContainer.getComponentAt(copyPosition).setBackground(selectElement);
                    }
                    if (copyRevocable != null) {
                        copyRevocable.revoke();
                        copyPosition = 0;
                    }
                    if (copyData.contains(dataList.get(i))) {
                        check_number--;
                        copyData.remove(dataList.get(i));
                        tv_selection.setText(check_number + " selection");
                        listContainer.getComponentAt(i).setBackground(normalElement);
                        return;
                    }

                    for (ItemModel copyDatum : copyData) {
                        if (dataList.get(i).equals(copyDatum)) {
                            isRepeat = true;
                            break;
                        }
                    }

                    if (!isRepeat) {
                        check_number++;
                        copyData.add(0, dataList.get(i));
                        tv_selection.setText(check_number + " selection");
                        listContainer.getComponentAt(i).setBackground(selectElement);
                    } else {
                        isRepeat = false;
                    }
                }
            }
        });
    }

    private void addCopy() {
        temp.clear();
        temp.addAll(dataList);
        p:
        for (int tempPosition = 0; tempPosition < temp.size(); tempPosition++) {
            for (ItemModel copyDatum : copyData) {
                if (temp.get(tempPosition).equals(copyDatum)) {
                    if (copyDatum.isFooter()) {
                        model = copyDatum;
                    } else {
                        ItemModel itemModel = new ItemModel(copyDatum.getTitle(), copyDatum.getMessage() + "  copy",
                                false, true, false, false,0,0);
                        dataList.add(tempPosition + 1, itemModel);
                        model = copyDatum;
                    }
                    break p;
                }
            }
        }
        copyData.remove(model);
        if (copyData.size() > 0) {
            addCopy();
        }
    }

    private void setCopyElement(int i) {
        if (copyTaskDispatcher == null) {
            copyTaskDispatcher = this.getUITaskDispatcher();
        }
        copyRevocable = copyTaskDispatcher.delayDispatch(copyRun, 0);
    }

    private class CopyRun implements Runnable {
        private final int position;

        public CopyRun(int i) {
            this.position = i;
            copyPosition = i;
        }

        @Override
        public void run() {
            setCopyElement(position);
            listContainer.getComponentAt(position).setBackground(selectElement);
        }

    }

    /**
     * dissMiss下滑滑动
     */
    public void dissMiss() {
        if (animationOut == null) {
            animationOut = new AnimatorValue();
            animationOut.setDuration(200);
            animationOut.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
            animationOut.setValueUpdateListener((animatorValue, v) -> {
                if (v == 1) {
                    dl_bottom.setVisibility(Component.HIDE);
                }
                dl_bottom.setTranslationY(v * dl_bottom.getHeight());
            });
        }
        animationOut.start();
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }


    private final ClickCallback mClickCallback = new ClickCallback() {
        @Override
        public void onClick(int index, ActionType type, String clickSource, Button collapse) {
            int clickHeadPos = 0;
            //找到点击的header位置
            for (int i = 0; i < dataList.size(); i++) {
                if (dataList.get(i).isHeader()) {
                    if (dataList.get(i).getTitle().split("/")[0].equals(dataList.get(index).getTitle().split("/")[0])) {
                        clickHeadPos = i;
                    }
                }
            }
            setSectionIsCollapsed(clickHeadPos, collapse);
        }
    };

    /**
     * Mark that a section is collapsed or not. By default sections are not collapsed and draw
     * all their child items. By "collapsing" a section, the child items are hidden.
     *
     * @param clickHeadPos clickHeadPos
     * @param collapse
     */
    private void setSectionIsCollapsed(int clickHeadPos, Button collapse) {
        ItemModel model = null;
        model = dataList.get(clickHeadPos);
        if (map.containsKey(model.getTitle())) {
            ((HeaderModel) dataList.get(clickHeadPos)).setToggle(false);
            ArrayList<ItemModel> data = map.get(model.getTitle());
            if (data.size() > 0) {
                dataList.addAll(clickHeadPos + 1, data);
            }
            map.remove(model.getTitle());
            if (collapse != null) {
                collapse.setBackground(new VectorElement(this, ResourceTable.Graphic_ic_expand_less_black_24dp));
            }
        } else {
            ((HeaderModel) dataList.get(clickHeadPos)).setToggle(true);
            ArrayList<ItemModel> itemModels = new ArrayList<>();
            for (int i2 = clickHeadPos; i2 < dataList.size(); i2++) {
                ItemModel itemModel = dataList.get(i2);
                if (!itemModel.isHeader() && itemModel.getMessage().split("/")[0].equals(model.getTitle())) {
                    itemModels.add(itemModel);
                }
                if (itemModel.isFooter() && itemModel.getMessage().split(" ")[3].equals(model.getTitle())) {
                    itemModels.add(itemModel);
                    break;
                }
            }
            if (map.containsKey(model.getTitle())) {
                itemModels.clear();
                return;
            }
            map.put(model.getTitle(), itemModels);
            dataList.removeAll(itemModels);
            if (collapse != null) {
                collapse.setBackground(new VectorElement(this, ResourceTable.Graphic_ic_expand_more_black_24dp));
            }
        }
        headerDecor.setDataList(dataList,true);
        adapter.notifyDataChanged();
    }
}
